/**
 *Copyright (c) 2024 watereyes
 * safetymanagement is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package com.koron.hazardsource.service.impl;

import java.text.NumberFormat;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.springframework.stereotype.Service;

import org.swan.bean.MessageBean;

import com.koron.common.bean.StaffBean;
import com.koron.common.generator.DefaultIdGenerator;
import com.koron.hazardsource.domain.PracticeTemplate;
import com.koron.hazardsource.mapper.PracticeTemplateMapper;
import com.koron.hazardsource.service.api.PracticeTemplateService;
import com.koron.hazardsource.util.BusinessCode;

@Service
public class PracticeTemplateServiceImpl implements PracticeTemplateService {

    private String[] codeArray = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};

    @SuppressWarnings({"deprecation"})
    @Override
    public MessageBean<?> save(StaffBean user, String name, Integer serial, String templateType, String pid, String remark) {
        MessageBean<?> msg = MessageBean.create(0, "SUCCESS", void.class);
        if (StringUtils.isEmpty(name) || StringUtils.isEmpty(templateType)) {
            msg.setCode(BusinessCode.MESSAGE_CODE_SERVICE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_SERVICE_EXCEPTION);
            return msg;
        }
        SessionFactory factory = new SessionFactory();
        try {
            PracticeTemplateMapper mapper = factory.getMapper(PracticeTemplateMapper.class);
            if (!StringUtils.isEmpty(pid)) {
                PracticeTemplate bean = mapper.queryById(pid);
                if (bean == null) {
                    factory.close(false);
                    msg.setCode(BusinessCode.MESSAGE_CODE_SERVICE_EXCEPTION);
                    msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_SERVICE_EXCEPTION);
                    return msg;
                }
                //更新父级子节点数量
                Integer subNumber = bean.getSubnumber();
                subNumber++;
                bean.setSubnumber(subNumber);
                mapper.update(bean);
            }
            String structureCode = generateCode(factory, name, templateType, pid);
            if (null == structureCode) {
                msg.setCode(BusinessCode.MESSAGE_CODE_GRID_NUMBER_GREAT);
                msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_GRID_NUMBER_GREAT);
                factory.close(false);
                return msg;
            }
            PracticeTemplate bean = new PracticeTemplate();
            bean.setAddTime(new Date());
            bean.setAddUser(user.getCode());
            bean.setAddUserName(user.getName());
            bean.setId(DefaultIdGenerator.getInstance().generateLongId());
            bean.setName(name);
            bean.setPid(pid);
            bean.setRemark(remark);
            bean.setSerial(serial);
            bean.setStructureCode(structureCode);
            bean.setTemplateType(templateType);
            bean.setSubnumber(0);
            mapper.insert(bean);

            factory.close();
        } catch (Exception e) {
            msg.setCode(BusinessCode.MESSAGE_CODE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_EXCEPTION);
            factory.close(false);
            return msg;
        }finally {
            if (null != factory){
                factory.close();
            }
        }
        return msg;
    }

    @SuppressWarnings({"deprecation", "resource"})
    @Override
    public MessageBean<?> delete(String id) {
        MessageBean<?> msg = MessageBean.create(0, "SUCCESS", void.class);
        SessionFactory factory = new SessionFactory();
        try {
            PracticeTemplateMapper mapper = factory.getMapper(PracticeTemplateMapper.class);
            Integer count = mapper.subsetCount(id);
            if (count > 0) {
                msg.setCode(BusinessCode.MESSAGE_CODE_EXCEPTION);
                msg.setDescription("存在下级节点,不能删除");
                factory.close();
                return msg;
            }
            PracticeTemplate bean = mapper.queryById(id);
            if (bean == null) {
                msg.setCode(BusinessCode.MESSAGE_CODE_SERVICE_EXCEPTION);
                msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_SERVICE_EXCEPTION);
                return msg;
            }
            if (!StringUtils.isEmpty(bean.getPid())) {
                PracticeTemplate parent = mapper.queryById(bean.getPid());
                Integer subnumber = parent.getSubnumber();
                subnumber--;
                parent.setSubnumber(subnumber);
                mapper.update(parent);
            }
            mapper.delete(id);
            factory.close();
        } catch (Exception e) {
            msg.setCode(BusinessCode.MESSAGE_CODE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_EXCEPTION);
            factory.close(false);
            return msg;
        }finally {
            if (null != factory){
                factory.close();
            }
        }
        return msg;
    }

    @SuppressWarnings("deprecation")
    @Override
    public MessageBean<?> update(StaffBean user, String id, String name, Integer serial, String remark, Integer subnumber) {
        MessageBean<?> msg = MessageBean.create(0, "SUCCESS", void.class);
        if (StringUtils.isEmpty(name)) {
            msg.setCode(BusinessCode.MESSAGE_CODE_SERVICE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_SERVICE_EXCEPTION);
            return msg;
        }
        SessionFactory factory = new SessionFactory();
        try {
            PracticeTemplateMapper mapper = factory.getMapper(PracticeTemplateMapper.class);
            PracticeTemplate bean = new PracticeTemplate();
            bean.setId(id);
            bean.setName(name);
            bean.setSerial(serial);
            bean.setRemark(remark);
            bean.setSubnumber(subnumber);
            bean.setUpdateTime(new Date());
            bean.setUpdateUser(user.getCode());
            bean.setUpdateUserName(user.getName());
            mapper.update(bean);
            factory.close();
        } catch (Exception e) {
            msg.setCode(BusinessCode.MESSAGE_CODE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_EXCEPTION);
            factory.close(false);
            return msg;
        }finally {
            if (null != factory){
                factory.close();
            }
        }
        return msg;
    }

    @SuppressWarnings({"deprecation", "rawtypes"})
    @Override
    public MessageBean<?> childList(String id) {
        MessageBean<List> msg = MessageBean.create(0, "SUCCESS", List.class);
        SessionFactory factory = new SessionFactory();
        try {
            PracticeTemplateMapper mapper = factory.getMapper(PracticeTemplateMapper.class);
            msg.setData(mapper.queryByPid(id));
            factory.close();
        } catch (Exception e) {
            msg.setCode(BusinessCode.MESSAGE_CODE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_EXCEPTION);
            factory.close(false);
            return msg;
        }
        return msg;
    }

    @SuppressWarnings({"deprecation", "rawtypes"})
    @Override
    public MessageBean<?> list(String templateType, String id) {
        MessageBean<List> msg = MessageBean.create(0, "SUCCESS", List.class);
        if (StringUtils.isEmpty(templateType) && StringUtils.isEmpty(id)) {
            msg.setCode(BusinessCode.MESSAGE_CODE_SERVICE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_SERVICE_EXCEPTION);
            return msg;
        }
        SessionFactory factory = new SessionFactory();
        try {
            PracticeTemplateMapper mapper = factory.getMapper(PracticeTemplateMapper.class);
            List<PracticeTemplate> practiceTemplates = mapper.queryByType(templateType);
            if (practiceTemplates != null && !practiceTemplates.isEmpty()) {
                List<PracticeTemplate> collect = practiceTemplates.stream().filter(template -> StringUtils.isBlank(template.getPid())).collect(Collectors.toList());
                if (collect != null && !collect.isEmpty()) {
                    collect.stream().forEach(one -> construct(one, practiceTemplates));
                }
                msg.setData(collect);
            } else {
                msg.setData(Collections.EMPTY_LIST);
            }
            //msg.setData(mapper.queryByIdOrType(templateType, id));
            factory.close();
        } catch (Exception e) {
            msg.setCode(BusinessCode.MESSAGE_CODE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_EXCEPTION);
            factory.close(false);
            return msg;
        }finally {
            if (null != factory){
                factory.close();
            }
        }
        return msg;
    }


    private void construct(PracticeTemplate root, List<PracticeTemplate> nodes) {
        List<PracticeTemplate> collect = nodes.stream().filter(node -> StringUtils.isNotBlank(node.getPid()) &&  node.getPid().equals(root.getId())).collect(Collectors.toList());
        if (null != collect && !collect.isEmpty()) {
            root.setTemplateChildren(collect);
            collect.forEach(template -> construct(template, nodes));
        }
    }

    @SuppressWarnings({"deprecation", "rawtypes"})
    @Override
    public MessageBean<?> allList(String templateType) {
        MessageBean<List> msg = MessageBean.create(0, "SUCCESS", List.class);
        if (StringUtils.isEmpty(templateType)) {
            msg.setCode(BusinessCode.MESSAGE_CODE_SERVICE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_SERVICE_EXCEPTION);
            return msg;
        }
        SessionFactory factory = new SessionFactory();
        try {
            PracticeTemplateMapper mapper = factory.getMapper(PracticeTemplateMapper.class);
            msg.setData(mapper.queryByType(templateType));
            factory.close();
        } catch (Exception e) {
            msg.setCode(BusinessCode.MESSAGE_CODE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_EXCEPTION);
            factory.close(false);
            return msg;
        }
        return msg;
    }

    @SuppressWarnings({"deprecation"})
    @Override
    public MessageBean<?> details(String id) {
        MessageBean<PracticeTemplate> msg = MessageBean.create(0, "SUCCESS", PracticeTemplate.class);
        SessionFactory factory = new SessionFactory();
        try {
            PracticeTemplateMapper mapper = factory.getMapper(PracticeTemplateMapper.class);
            msg.setData(mapper.queryById(id));
            factory.close();
        } catch (Exception e) {
            msg.setCode(BusinessCode.MESSAGE_CODE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_EXCEPTION);
            factory.close(false);
            return msg;
        }
        return msg;
    }

    private String generateCode(SessionFactory factory, String name, String templateType, String pid) {
        StringBuffer structureCode = new StringBuffer();
        PracticeTemplateMapper mapper = factory.getMapper(PracticeTemplateMapper.class);
        if (StringUtils.isEmpty(pid)) {
            Integer count = mapper.serialQuery(templateType, pid);
            if (count > codeArray.length - 1) {
                return null;
            }
            return codeArray[count];
        } else {
            PracticeTemplate parent = mapper.queryById(pid);
            String pCode = parent.getStructureCode();
            if (pCode.length() == 1) {
                //第二级网格
                Integer count = mapper.serialQuery(templateType, pid);
                if (count > codeArray.length - 1) {
                    return null;
                }
                structureCode.append(pCode).append(codeArray[count]);
                return structureCode.toString();
            }
            NumberFormat nf = NumberFormat.getInstance();
            nf.setGroupingUsed(false);
            nf.setMaximumIntegerDigits(2); // 设置最大整数位数
            nf.setMinimumIntegerDigits(2); // 设置最小整数位数
            String str = name.replaceAll("\\d+", "");
            str = "%" + str + "%";
            Integer nameCount = mapper.nameCount(pid, str);//判断名称是否重复
            if (nameCount > 0) {
                List<PracticeTemplate> list = mapper.queryByName(pid, str);
                PracticeTemplate brother = list.get(0);
                String bCode = brother.getStructureCode();
                bCode = bCode.substring(0, bCode.length() - 2);
                nameCount++;
                structureCode.append(bCode).append(nf.format(nameCount));
                return structureCode.toString();
            } else {
                List<PracticeTemplate> list = mapper.queryByPid(pid);
                Integer count = 0;
                for (PracticeTemplate bean : list) {
                    String code = bean.getStructureCode();
                    if (code.endsWith("01")) {
                        count++;
                    }
                }
                if (count > codeArray.length - 1) {
                    return null;
                }
                structureCode.append(pCode).append(codeArray[count]).append("01");
                return structureCode.toString();
            }
        }
    }
}
